unit u34063Calc;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, uBaseCalcForm, StdCtrls, ExtCtrls;

type
  Tfm34063 = class(TfmBaseCalcForm)
    edVIn: TLabeledEdit;
    edVOut: TLabeledEdit;
    edIOut: TLabeledEdit;
    edVRipple: TLabeledEdit;
    edFmin: TLabeledEdit;
    Button1: TButton;
    edCt: TLabeledEdit;
    edIpk: TLabeledEdit;
    edRsc: TLabeledEdit;
    edLMin: TLabeledEdit;
    edCo: TLabeledEdit;
    laCt: TLabel;
    laIpk: TLabel;
    laRsc: TLabel;
    laLmin: TLabel;
    laCo: TLabel;
    laVIn: TLabel;
    laVout: TLabel;
    laIout: TLabel;
    laVripple: TLabel;
    laFMin: TLabel;
    edR1: TLabeledEdit;
    edR2: TLabeledEdit;
    laR1: TLabel;
    laR2: TLabel;
    laIpkHint: TLabel;
    Panel1: TPanel;
    imgMain: TImage;
    Bevel1: TBevel;
    edAvo: TLabeledEdit;
    laAvo: TLabel;
    Shape1: TShape;
    procedure DoCalcMe(Sender: TObject);
  private
    { Private declarations }
    vin,
    vout,
    vsat,
    fmin,
    iout,
    vf,
    vripple: single;
    
    procedure CalcStepUp;
    procedure CalcStepDown;
    procedure CalcInverter;
    procedure formatIpkHint(aIpk: single);
  public
    { Public declarations }
    class function CalcFriendlyName: string; override;
    class function RunKey: string; override;
    class procedure InvokeCalc; override;
    
    procedure AfterConstruction; override;
  end;

var
  fm34063: Tfm34063;

implementation

uses uFormReg, uLocalization;

{$R *.dfm}

const
  r48: Array[0..68] of single = (
	  1.0, 1.1, 1.2, 1.3, 1.5, 1.6, 1.8, 2.0, 2.2, 2.4, 2.7, 3.0,
	  3.3, 3.6, 3.9, 4.3, 4.7, 5.1, 5.6, 6.2, 6.8, 7.5, 8.2, 9.1,
	  10.0, 11.0, 12.0, 13.0, 15.0, 16.0, 18.0, 20.0, 22.0, 24.0, 27.0, 30.0,
	  33.0, 36.0, 39.0, 43.0, 47.0, 51.0, 56.0, 62.0, 68.0, 75.0, 82.0, 91.0,    100.0, 120.0, 150.0, 180.0, 200.0, 220.0, 240.0, 270.0, 300.0,    330.0, 360.0, 390.0, 430.0, 470.0, 510.0, 560.0, 620.0, 680.0, 750.0, 820.0, 910.0);
// choose feedback resistors for output voltage vo
// output voltage is Vout=1.25(1+R2/R1)
//
function calcr1r2(vo: single; out fr1,fr2: single): single;
var i,j: integer;
    bv,v: single;
begin
  bv := vo*1000;
	vo := abs(vo);
	for j := Low(r48) to High(r48) do begin	// go through R1 values
		for i := Low(r48) to High(r48) do begin	// and try all R2 values
			v := 1.25*(1+(r48[i]/r48[j]));
			if (abs(vo-v) < abs(vo-bv)) then begin
				fr2 := r48[i];
				fr1 := r48[j];
				bv := v;
			end;
		end;
	end;
	Result := bv;
end;

{ Tfm34063 }

procedure Tfm34063.AfterConstruction;
begin
  inherited;
  vsat := 1.0;
  vf := 0.4;
  SetLabels('VIn', getString('#global\uin'), getString('#global\volt'));
  SetLabels('VOut', getString('#global\uout'), getString('#global\volt'));
  SetLabels('IOut', getString('#global\iout'), getString('#global\mA'));
  SetLabels('VRipple', getLocaleString('vripple'), getString('#global\mV'));
  SetLabels('FMin', getLocaleString('minfreq'), getString('#global\kHz'));
  SetLabels('Ct', getLocaleString('tcap'), getString('#global\pF'));
  SetLabels('Ipk', getLocaleString('ipk'), getString('#global\amp'));
  SetLabels('Rsc', getLocaleString('rsense'), getString('#global\Ohm'));
  SetLabels('LMin', getLocaleString('mincoil'), getString('#global\uH'));
  SetLabels('Co', getLocaleString('outcap'), getString('#global\uF'));
  SetLabels('R1','R1', getString('#global\kOhm'));
  SetLabels('R2','R2', getString('#global\kOhm'));
  SetLabels('Avo', getLocaleString('avo'), getString('#global\volt'));
  Button1.Caption := getString('#global\calcbtn');
  laIpkHint.Caption := getLocaleString('ipkidle');
  
  LoadPictureFromRes(imgMain.Picture,'DOWN34');
end;

class function Tfm34063.CalcFriendlyName: string;
begin
  Result := 'MC34063 Calculator';
end;

procedure Tfm34063.CalcInverter;
var ipk: single;
    ct: double;
    tontoff,
    sumtontoff,
    toff,
    ton: single;
    rsc,
    lmin,
    co,r1,r2,avo: single;
begin
  LoadPictureFromRes(imgMain.Picture,'INV34');

  // calculate some temporary values
	tontoff := (abs(vout)+vf)/(vin-vsat);
	sumtontoff := 1/fmin;
	toff := sumtontoff/(tontoff+1);
	ton := sumtontoff-toff;
	// calculate components
  ct := (4.5*0.00001*tOn)*1e12;
	ipk := 2*iOut*(tontoff+1);

	//cbExtSwitch.Checked := (ipk>1.5);
  FormatIpkHint(ipk);

	rsc := 0.3/ipk;
	lmin := (((vin-vsat)/ipk)*ton)*1000000;
	co := 9*((iout*ton)/vripple)*1000000;

	edCt.Text := Format('%.f', [ct]);//+" pF\n"+
	edIpk.Text := Format('%.2f', [ipk]);//+" mA\n"+
	edRsc.Text := Format('%.3f', [rsc]);//+" Ohm\n"+
	edLmin.Text := Format('%.f', [lmin]);//+" uH\n"+
	edCo.Text := Format('%.f', [co]);//+" uF\n"+

	//edR.Text := 180;// Ohm\n"+
  avo := calcr1r2(vOut,r1,r2);
	edR1.Text := Format('%.2f', [r1]);
	edR2.Text := Format('%.2f', [r2]);
  edAvo.Text := Format('%f', [round(avo*100.0)/100.0]);
end;

procedure Tfm34063.CalcStepDown;
var ipk: single;
    ct: double;
    tontoff,
    sumtontoff,
    toff,
    ton: single;
    rsc,
    lmin,
    co: single;
    r1,r2,avo: single;
begin
  LoadPictureFromRes(imgMain.Picture,'DOWN34');

  // calculate some temporary values
	tontoff := (abs(vout)+vf)/(vin-vsat);
	sumtontoff := 1/fmin;
	toff := sumtontoff/(tontoff+1);
	ton := sumtontoff-toff;

	// calculate components
  ct := (4.5*0.00001*tOn)*1e12;
	ipk := 2*iOut;

  FormatIpkHint(ipk);

	rsc := 0.30/ipk;
  lmin := (((vin-vsat-vout)/ipk)*ton)*1e6;
  co := ((ipk*sumtontoff)/(8*vripple))*1e6;

	edCt.Text := Format('%.f', [ct]);//+" pF\n"+
	edIpk.Text := Format('%.2f', [ipk]);//+" mA\n"+
	edRsc.Text := Format('%.3f', [rsc]);//+" Ohm\n"+
	edLmin.Text := Format('%.f', [lmin]);//+" uH\n"+
	edCo.Text := Format('%.f', [co]);//+" uF\n"+

	//edR.Text := 180;// Ohm\n"+
  avo := calcr1r2(vOut,r1,r2);
	edR1.Text := Format('%.2f', [r1]);//+"k
	edR2.Text := Format('%.2f', [r2]);
  edAvo.Text := Format('%f', [round(avo*100.0)/100.0]);
end;

class procedure Tfm34063.InvokeCalc;
begin
  Application.CreateForm(Tfm34063, fm34063);
  fm34063.Show;
  inherited;
end;

class function Tfm34063.RunKey: string;
begin
  Result := '34063';
end;

procedure Tfm34063.CalcStepUp;
var ipk: single;
    ct: double;
    tontoff,
    sumtontoff,
    toff,
    ton: single;
    rsc,
    lmin,
    co,r1,r2,avo: single;
begin
  LoadPictureFromRes(imgMain.Picture,'UP34');
  
  tontoff := (vOut+vf-vIn)/(vIn-vSat);
	sumtontoff := 1/fmin;
	tOff := sumtontoff/(tontoff+1);
	tOn := sumtontoff-toff;

  // calculate components
	ct := (4.5*0.00001*tOn)*1e12;
	ipk := 2*iOut*(tOntOff+1);
  formatIpkHint(ipk);

	rsc := 0.3/ipk;
	lmin := (((vin-vsat)/ipk)*ton)*1000000;
	co := 9*((iout*ton)/vripple)*1000000;

	edCt.Text := Format('%.f', [ct]);//+" pF\n"+
	edIpk.Text := Format('%.2f', [ipk]);//+" mA\n"+
	edRsc.Text := Format('%.3f', [rsc]);//+" Ohm\n"+
	edLmin.Text := Format('%.f', [lmin]);//+" uH\n"+
	edCo.Text := Format('%.f', [co]);//+" uF\n"+
	//edR.Text := 180;// Ohm\n"+
	//edR1.Text := r1;//+"k
	//edR2.Text := r2;//+"k ("+Math.round(avo*100.0)/100.0+"V)";
  avo := calcr1r2(vOut,r1,r2);
	edR1.Text := Format('%.2f', [r1]);//+"k
	edR2.Text := Format('%.2f', [r2]);
  edAvo.Text := Format('%f', [round(avo*100.0)/100.0]);
end;
	
procedure Tfm34063.DoCalcMe(Sender: TObject);
begin
  if not CheckField2(edVIn, vIn, 2.9,40.1) then exit;
  if not CheckField2(edVOut, vOut) then exit;

  iOut := checkField(edIOut)/1000;
  fmin := checkField(edFMin)*1000;
  vRipple := checkField(edVRipple)/1000;

  if (abs(vin-vout)<(vsat+vf)) then begin
    HighliteErrorField(edVOut);
    exit; // error in params
  end;

  if (vOut<0) then CalcInverter
  else
  if (vOut>vIn) then CalcStepUp
  else CalcStepDown;
end;

procedure Tfm34063.formatIpkHint(aIpk: single);
begin
  laIpkHint.Caption := getLocaleString('ipkok');
  if (aipk>=1.5) then begin
    edIpk.Font.Color := clRed;
    edIpk.Font.Style := [fsBold];
    laIpkHint.Caption := getLocaleString('ipkext');
  end else
  if (aipk>=0.7) then begin
    edIpk.Font.Color := clMaroon;
    laIpkHint.Caption := getLocaleString('ipkhot');
  end else
    edIpk.ParentFont := true;
end;

initialization
  RegisterCalc(Tfm34063);

end.
